import time
import json
import datetime
import uuid

from django.db import models
from django.db.models import F
from django.db.models.functions import TruncDate
from django.db.models import Sum, Count
from django.utils import timezone
from dateutil.relativedelta import relativedelta
from django.contrib.auth import get_user_model
from core.tools.encryption import hashlib_md5
from core.tools.func_utils import funcUtils
from chinese_calendar import is_workday
from .client import CoffeeApi
from .config import system_user, dhq_quota
from apps.coffee_admin.utils import filter_channel_1, filter_channel_2, filter_channel_3

User = get_user_model()


class Banner(models.Model):
    urlType = ((1, "url跳转"), (2, "无跳转"), (3, "小程序跳转"))
    image = models.CharField(max_length=256, verbose_name="图片地址")
    url = models.CharField(max_length=256, verbose_name="跳转地址", blank=True, null=True)
    url_type = models.IntegerField(choices=urlType, verbose_name="跳转类型")
    name = models.CharField(blank=True, null=True, max_length=16, verbose_name="名称")

    class Meta:
        verbose_name = "banner"
        verbose_name_plural = verbose_name


# 行业
class Trade(models.Model):
    name = models.CharField(verbose_name="名称", max_length=16)
    key = models.CharField(verbose_name="key", max_length=32, db_index=True, blank=True, null=False)
    order = models.IntegerField(verbose_name="排序", default=0)
    is_show = models.BooleanField(verbose_name="是否显示", default=True)

    class Meta:
        verbose_name = "商家所属行业"
        verbose_name_plural = verbose_name
        ordering = ("order",)

    def __str__(self):
        return self.name


# 系统分类
class SysType(models.Model):
    name = models.CharField(verbose_name="名称", max_length=16)
    key = models.CharField(verbose_name="key", max_length=16)

    class Meta:
        verbose_name = "系统分类"
        verbose_name_plural = verbose_name


# 咖啡机管理
class CoffeeClient(models.Model):
    deviceType = ((1, "柜式"), (2, "台式"),)
    store = models.CharField(max_length=16, verbose_name="门店")
    channel = models.ForeignKey("Channel", verbose_name="渠道")
    lon = models.CharField(max_length=16, verbose_name="经度")
    lat = models.CharField(max_length=16, verbose_name="纬度")
    city = models.CharField(verbose_name="城市", max_length=16, blank=True, null=True)
    group_code = models.CharField(verbose_name="群聊码", blank=True, null=True, max_length=256)
    address = models.CharField(max_length=32, verbose_name="咖啡机地址")
    sign = models.CharField(max_length=5, db_index=True, verbose_name="机器标识")
    title = models.CharField(max_length=32, verbose_name="标题", blank=True, null=True)
    remark = models.CharField(max_length=32, verbose_name="备注", blank=True, null=True)
    remark2 = models.CharField(max_length=128, verbose_name="备注2", blank=True, null=True)
    remark3 = models.CharField(max_length=128, verbose_name="备注3", blank=True, null=True)
    status = models.BooleanField(verbose_name="展示", db_index=True, default=True)
    service = models.BooleanField(verbose_name="支持取杯", default=True, db_index=True)
    device_type = models.IntegerField(choices=deviceType, verbose_name="咖啡机类型", default=1)
    goods_tag = models.CharField(max_length=20, verbose_name="优惠标记", blank=True, null=True,
                                 help_text="如果是下划线结尾就是机器加手机号=设备_用户手机号, 某人使用某银行卡在此机器上能使用优惠，"
                                           "配置不同银行卡活动，某人在此机器上可以享受优惠")
    is_used = models.BooleanField(default=True, verbose_name="是否使用中")
    sort_level = models.IntegerField(default=0, help_text="排序,0不参与排序，1往上最大排序最高", verbose_name="排序")

    class Meta:
        verbose_name = "咖啡机管理"
        verbose_name_plural = verbose_name


# coffee 商品管理
class Coffee(models.Model):
    coffeeType = ((1, "美式"), (2, "花式"), (3, "免费券C的商品"))
    # coffeeType3 = [811, 802, 800]  # 811醇香牛奶、 802 巧克力牛奶, 800 香浓巧克力
    coffeeType3 = []  # 811醇香牛奶、 802 巧克力牛奶, 800 香浓巧克力 # 变成空了
    c_type = models.IntegerField(default=1, verbose_name="类型")
    price = models.IntegerField(verbose_name="价格", help_text="以分为单位")
    name = models.CharField(verbose_name="名称", max_length=16)
    image = models.CharField(verbose_name="图片地址", max_length=128, blank=True, null=True)
    pid = models.CharField(verbose_name="产品id", max_length=16)
    sys_type = models.ManyToManyField(SysType, blank=True, null=True, verbose_name="系统分类")
    device_type = models.IntegerField(choices=CoffeeClient.deviceType, verbose_name="对应的设备类型", default=1)
    show = models.BooleanField(default=True, verbose_name="是否显示")

    class Meta:
        verbose_name = "Coffee"
        verbose_name_plural = verbose_name


# 渠道管理
class Channel(models.Model):
    channelType = ((1, "商户"), (2, "门店"), (3, "门店售后员"))
    name = models.CharField(max_length=16, verbose_name="渠道名称")
    key = models.CharField(max_length=16, verbose_name="标识", db_index=True)
    secret = models.CharField(max_length=64, verbose_name="秘钥")
    num = models.IntegerField(verbose_name="赠送数量", blank=True, null=True)
    text = models.TextField(verbose_name="广告语", blank=True, null=True, max_length=64)
    trade = models.ForeignKey("Trade", verbose_name="行业", blank=True, null=True)
    img = models.CharField(verbose_name="列表图", blank=True, null=True, max_length=256)
    big_img = models.CharField(verbose_name="详情图", blank=True, null=True, max_length=256)
    url = models.CharField(verbose_name="需要跳转的url", blank=True, null=True, max_length=256)
    channel_type = models.IntegerField(choices=channelType, default=1, verbose_name="类型")
    parent = models.ForeignKey("self", verbose_name="父级", blank=True, on_delete=models.DO_NOTHING, null=True,
                               related_name="children")
    show = models.BooleanField(verbose_name="显示", default=True)

    class Meta:
        verbose_name = "coffee渠道"
        verbose_name_plural = verbose_name

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        if self._state.adding:
            self.secret = hashlib_md5(self.key + str(time.time()))
        return super(Channel, self).save()

    def get_children(self, instance):
        channel_queryset = Channel.objects.none()
        if self.channel_type == 1:
            type_2_queryset = instance.children.all()
            channel_queryset |= channel_queryset
            for i in type_2_queryset:
                channel_queryset |= i.children.all()
        elif self.channel_type == 2:
            channel_queryset |= instance.children.all()
        else:
            channel_queryset |= instance

    def __str__(self):
        return self.name


class CouponInfoManager(models.Manager):
    # 获取可用的优惠券数量
    def get_useful_sum(self, user, c_type, quota=0):
        queryset = self.filter(c_type=c_type, user=user, expired=False, used=False, status=1, can_share=True)
        if quota:
            queryset = queryset.filter(quota=quota)
        return queryset.count()

    # group by 给前端列表使用
    @classmethod
    def group_by(cls, queryset):
        return queryset.values("quota", "c_type", "expire_time", "status").annotate(counts=Count("id"))

    # 查询可以使用的券
    def can_use_coupon(self, user):
        # c_type_list = []
        # for i in CouponInfo.cType:
        #     if i[0] != 0:
        #         c_type_list.append(i[0])
        c_type_list = CouponInfo.show_c_type_list  # 7 9 2

        last_day = datetime.datetime.now() - datetime.timedelta(days=1)
        queryset = self.filter(user=user, given=False, used=False, expired=False, expire_time__gte=last_day,
                               c_type__in=c_type_list, status=1)
        # queryset9 = self.filter(user=user, given=False, used=False, expired=False, expire_time__gte=last_day,
        #                        c_type=9, status=1)
        # queryset2 = self.filter(user=user, given=False, used=False, expired=False, expire_time__gte=last_day,
        #                        c_type=2, status=1)
        # queryset = queryset.union(queryset9).union(queryset2)
        return queryset

    # 给前端提交订单时使用
    @classmethod
    def group_by_type_and_quota(cls, queryset):
        return queryset.values("c_type", "quota").annotate(counts=Count("id")).order_by("c_type")

    # 给前端券统计用
    @classmethod
    def group_by_counts(cls, queryset):
        return queryset.values("c_type").annotate(counts=Count("id")).order_by("c_type")

    # 分享后减少券
    def update_num_by_type_num(self, c_type, user, num, quota=0):
        queryset = self.filter(c_type=c_type, given=False, user=user, expired=False, used=False, can_share=True)
        if quota:
            queryset = queryset.filter(quota=quota)
        update_queryset = queryset[:num]
        id_list = update_queryset.values_list("id", flat=True)
        id_list = list(id_list)
        return id_list

    # 过期后返回券
    def return_coupon(self):
        pass

    # 创建默认立减券
    def create_coupon(self, num, user, c_type=2, channel=None, name="立减券", expire_days=6, quota=600, bag=None):
        expire_time = datetime.datetime.today() + relativedelta(days=expire_days)
        create_time = datetime.datetime.now()
        if not channel:
            channel = Channel.objects.get(key="iamcoffee")
        if isinstance(channel, str):
            channel = Channel.objects.get(key=channel)
        return self.bulk_create_by_normal(num, name, user, channel, expire_time, create_time, c_type, quota=quota,
                                          bag=bag)

    # 批量生成
    def bulk_create_by_normal(self, num, name, user, channel, expire_time, create_time, c_type, quota=600,
                              everyday_make=False, active_key="0", is_special=False, can_share=True, bag=None,
                              old_user_id=None, h5_active=None, sales_type=1, is_laxin=False):
        queryset_list = []
        model = self.model
        if isinstance(user, User):
            user_id = user.id
        else:
            user_id = user
        if not old_user_id:
            old_user_id = user_id
        if channel:
            pass
        else:
            channel = Channel.objects.filter(key="iamcoffee").first()
        for i in range(num):
            code = funcUtils.makeCouponCode()
            queryset_list.append(
                model(
                    is_laxin=is_laxin,
                    sales_type=sales_type,
                    channel=channel,
                    name=name,
                    quota=quota,
                    expire_time=expire_time,
                    create_time=create_time,
                    c_type=c_type,
                    user_id=user_id,
                    code=code,
                    everyday_make=everyday_make,
                    active_key=active_key,
                    is_special=is_special,
                    can_share=can_share,
                    bag=bag,
                    old_user_id=old_user_id,
                    h5_active=h5_active

                )
            )
        return self.bulk_create(queryset_list)

    # 单个生成
    def one_create_by_normal(self, user, expire_days=3, c_type=2, quota=600, name="立减券", channel=None, status=1,
                             limit=99999):
        if not channel:
            channel = Channel.objects.get(key="iamcoffee")
        if isinstance(channel, str):
            channel = Channel.objects.get(key=channel)
        expire_time = datetime.datetime.today() + relativedelta(days=expire_days)
        create_time = datetime.datetime.now()
        code = funcUtils.makeCouponCode()
        return self.create(
            channel=channel,
            name=name,
            quota=quota,
            expire_time=expire_time,
            create_time=create_time,
            c_type=c_type,
            user=user,
            code=code,
            status=status,
            limit=limit
        )

    def verify_coupon(self, user_id, c_type, quota=0):
        last_day = datetime.datetime.now() - datetime.timedelta(days=1)
        queryset = self.filter(user_id=user_id, given=False, used=False, expired=False, expire_time__gte=last_day,
                               c_type=c_type, status=1, quota=quota)
        return queryset.exists()


# 券管理
class CouponInfo(models.Model):
    # cType = ((0, "没使用券"), (1, "免费A"), (2, "立减券"), (3, "兑换券"), (4, "对折券"), (5, "现金券"), (6, "免费B"))
    # 现在只显示 全部、免费券、立减券、2元兑换券  2，7，9
    cType = (
        (-1, "每天减一毛"), (0, "没使用券"), (1, "免费A"), (2, "立减券"), (3, "兑换券A"), (6, "免费B"),
        (7, "免费券"),
        (8, "兑换券B"), (9, "两元兑换券"), (10, "微信商户配置活动"), (11, "免费券C"))
    # show_c_type_list = [2, 7, 9, 1, 6]
    show_c_type_list = [7, 1, 11, 6, 9, 2]
    freeCouponType = [1, 6, 7, 11]
    Status = ((1, "可使用"), (2, "发放中"), (3, "已退"),)  # 卡包生成的可以退
    salesType = ((1, "未消费"), (2, "到店消费"))
    sales_type = models.IntegerField(verbose_name="售卖类型", default=1, choices=salesType)
    limit = models.IntegerField(verbose_name="受限额度,默认最大值", default=99999)
    is_special = models.BooleanField(default=False, verbose_name="特殊(特定渠道机器使用)")
    active_key = models.CharField(verbose_name="活动key", max_length=16, db_index=True, default="0")
    given = models.BooleanField(verbose_name="已赠出", db_index=True, default=False)
    code = models.CharField(unique=True, max_length=16)
    name = models.CharField(verbose_name="券名称", max_length=16)
    quota = models.IntegerField(default=0, verbose_name="额度", help_text="只有立减券有额度")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    expire_time = models.DateField(default=datetime.date.today() + relativedelta(years=1))
    user = models.ForeignKey(User, verbose_name="用户", related_name="coupon_user_set")
    channel = models.ForeignKey("Channel", verbose_name="渠道")
    c_type = models.IntegerField(verbose_name="券的类型", choices=cType, db_index=True)
    used = models.BooleanField(default=False, verbose_name="被使用完", db_index=True)
    expired = models.BooleanField(default=False, verbose_name="过期", db_index=True)
    everyday_make = models.BooleanField(verbose_name="是否每天生成", default=False, db_index=True)
    status = models.IntegerField(verbose_name="券状态", db_index=True, default=1, choices=Status)
    can_share = models.BooleanField(verbose_name="可以分享", default=True)
    bag = models.IntegerField(blank=True, null=True, verbose_name="卡包id")
    old_user_id = models.IntegerField(blank=True, null=True, verbose_name="最开始领取的人")
    h5_active = models.CharField(blank=True, null=True, verbose_name="h5领券活动", max_length=32)
    is_laxin = models.BooleanField(default=False, verbose_name="是否是好友拉新获得券")
    objects = CouponInfoManager()

    class Meta:
        verbose_name = "咖啡券详情"
        verbose_name_plural = verbose_name


# 赠送记录管理
class GiveRecordManager(models.Manager):
    def create_record(self, coupon_id_list, num, own_user, c_type, give_type=3, receive_user=None, status=1, score=1):
        """
        这个逻辑不涉及系统赠送券了
        :param coupon_id_list:
        :param num:
        :param own_user:
        :param c_type:
        :param receive_user:
        :param status: ((1, "已接收"), (2, "未接收"), (3, "已返回"),)
        :param give_type: 转账类型((1, "分享链接"), (2, "扫码"), (3, "手机号"), (4, "系统赠送"),  (5, "门店售货员"),)
        :param score: 来源((1, "好友"), (2, "渠道"),)
        :return:
        """
        instance = self.create(
            own_user=own_user,
            receive_user=receive_user,
            c_type=c_type,
            num=num,
            give_type=give_type,
            status=status,
            score=score,
            coupon=json.dumps(coupon_id_list),
        )
        return instance

    # 转赠记录系统赠送记录
    def create_record_by_system(self, status, num, receive_user, instance=None, c_type=2, coupon=None, score=1,
                                order_score=None):
        """
        :param status:
        :param num:
        :param receive_user:
        :param instance:
        :param c_type:
        :param coupon:
        :param score:
        :param order_score: 订单来源券
        :return:
        """
        self.create(
            own_user=User.objects.get(mobile=system_user),
            receive_user=receive_user,
            c_type=c_type,
            num=num,
            give_type=4,
            status=status,  # 如果接收人是已经注册的，直接就是1，已经接收
            parents=instance,
            coupon=coupon,
            score=score,
            order_score=order_score
        )

    # 查找券记录
    def record_queryset(self, user, status=2):
        return self.filter(status=status, receive_user=user).order_by("create_time")

    @classmethod
    def new_user_login(cls, user):
        if user.coffee_new_user:  # 如果是coffee新用户
            # 查看转赠记录，找到需要更新的coffee券，老用户就已经赠送过去了，就不需要走这个逻辑了
            # GiveRecord.objects.update_coupon_by_record(user)  # 新用户先去掉送的13元券
            pass

    # 登录进来通过记录更新优惠券数量（用户登录后的逻辑）
    def update_coupon_by_record(self, user):
        queryset = self.record_queryset(user)  # 赠送记录列表
        coupon_id_list = []
        for i in queryset:
            self.create_record_by_after(i)
            coupon_id_list.extend(json.loads(i.coupon))
        CouponInfo.objects.filter(id__in=coupon_id_list).update(user=user, given=False)
        queryset.update(status=1)
        if queryset:  # 如果领过券了 那么就变成老用户
            user.coffee_new_user = False
            user.save()

    # 只有新用户并且不是客户经理才走这个逻辑，才赠送券
    def create_record_by_after(self, recode_instance):
        receive_user = recode_instance.receive_user
        # if receive_user.coffee_new_user:  # 如果是新用户
        # own_user = recode_instance.own_user
        # if not own_user.is_coffee_manager:  # 并且不是客户经理, 转发之后赠送
        #     c_num = 2  # 给分享人两张券
        #     self.create_record_by_system(1, c_num, own_user, instance=recode_instance)  # 创建标记数量的券记录
        #     CouponInfo.objects.create_coupon(c_num, own_user)  # 创建对应的券数量
        # 并且将
        receive_user.coffee_new_user = False
        receive_user.save()

    # --------------------------------------------下面是以前养券逻辑-----------------------------------------------
    # 创建转赠记录 通过链接（用户确认领券之后再进行操作）以前做养券的逻辑
    # def create_record_by_after_old(self, recode_instance):
    #     own_user = recode_instance.own_user
    #     receive_user = recode_instance.receive_user
    #     c_type = recode_instance.c_type
    #     num = recode_instance.num
    #
    #     if c_type == 1:  # 免费券
    #         # 创建系统赠送的转赠记录(这里是免费券，那么接收人得相应的数量系统赠送券)
    #         self.create_record_by_system(1, num, receive_user, instance=recode_instance)
    #         # 创建系统赠送的立减券
    #         CouponInfo.objects.create_coupon(num, receive_user)
    #     # 系统赠给赠送人相应数量的立减券 * 2
    #     if not own_user.is_coffee_manager:
    #         c_num = num * 2
    #         self.create_record_by_system(1, c_num, own_user, instance=recode_instance)  # 创建标记数量的券记录
    #         CouponInfo.objects.create_coupon(c_num, own_user)  # 创建对应的券数量
    #     return recode_instance

    # 通过已经注册的用户手机转赠创建转赠记录
    # def create_record_by_user_mobile(self, coupon_id_list, num, own_user, c_type, receive_user):
    #     instance = self.create(
    #         own_user=own_user,
    #         receive_user=receive_user,
    #         c_type=c_type,
    #         num=num,
    #         give_type=3,
    #         status=1,
    #         coupon=json.dumps(coupon_id_list),
    #     )
    #     if c_type == 1:  # 免费券
    #         self.create_record_by_system(1, num, receive_user, instance)
    #         CouponInfo.objects.create_coupon(num, receive_user)
    #     if not own_user.is_coffee_manager:  # 如果不是客户经理
    #         num *= 2  # 分享人得双倍数量的立减券
    #         self.create_record_by_system(1, num, own_user, instance)
    #         CouponInfo.objects.create_coupon(num, own_user)
    #     return instance

    # 通过未注册的用户手机转赠创建转赠记录，或者通过扫码转赠创建转赠记录
    def create_record_by_url(self, coupon_id_list, num, own_user, c_type, give_type=3, status=1, receive_user=None):
        # 创建转赠记录
        instance = self.create(
            own_user=own_user,
            c_type=c_type,
            num=num,
            give_type=give_type,
            receive_user=receive_user,
            status=status,
            coupon=json.dumps(coupon_id_list),
        )
        return instance
        # -----------------------------------------------养券逻辑end----------------------------------------------------


# 赠送记录 如果已经注册的用户，优惠券是直接到账
class GiveRecord(models.Model):
    receiveStatus = ((1, "已接收"), (2, "未接收"), (3, "已返回"),)
    giveType = ((1, "分享链接"), (2, "扫码"), (3, "手机号"), (4, "系统赠送"),)
    scoreType = ((1, "好友"), (2, "渠道"),)
    score = models.IntegerField(choices=scoreType, verbose_name="来源", default=1)
    give_type = models.IntegerField(verbose_name="赠送方式", choices=giveType, default=2)
    num = models.IntegerField(verbose_name="数量")
    status = models.IntegerField(verbose_name="状态接收", choices=receiveStatus, default=2)
    own_user = models.ForeignKey(User, verbose_name="拥有用户", related_name="give_record_own_user_set")
    receive_user = models.ForeignKey(User, verbose_name="接收用户", related_name="give_record_receive_user_set",
                                     blank=True, null=True)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    update_time = models.DateTimeField(verbose_name="创建时间", auto_now=True)
    coupon = models.TextField(verbose_name="操作的券列表", blank=True, null=True)
    c_type = models.IntegerField(verbose_name="券的类型", choices=CouponInfo.cType, db_index=True)
    parents = models.ForeignKey("self", verbose_name="由哪条转赠记录生成", blank=True, null=True,
                                related_name="give_record_child_set")
    order_score = models.OneToOneField("CoffeeOrder", blank=True, null=True, verbose_name="订单来源")
    objects = GiveRecordManager()

    def update_status_3(self, refund_user=None):
        """
        :param refund_user: 要退到哪个用户上面
        :return:
        """
        coupon_id_list = json.loads(self.coupon)
        if refund_user:
            CouponInfo.objects.filter(id__in=coupon_id_list).update(
                given=False,
                user=refund_user
            )
        else:
            CouponInfo.objects.filter(id__in=coupon_id_list).update(
                given=False,
            )
        self.status = 3
        self.save()

    class Meta:
        verbose_name = "转赠记录"
        verbose_name_plural = verbose_name
        ordering = ("-id",)


# 使用记录
class UseRecord(models.Model):
    Status = ((1, "正常"), (2, "退回"))
    coupon = models.ForeignKey(CouponInfo, verbose_name="对应的券")
    num = models.IntegerField(verbose_name="数量记录", default=1)
    order = models.OneToOneField("CoffeeOrder", verbose_name="订单", related_name="use_record")
    user = models.ForeignKey(User, verbose_name="用户")
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    status = models.IntegerField(choices=Status, default=1, verbose_name="状态")

    class Meta:
        verbose_name = "使用记录"
        verbose_name_plural = verbose_name


class CoffeeOrderManager(models.Manager):
    def cancel_orders(self):
        now_time = datetime.datetime.now()
        end_time = now_time - datetime.timedelta(hours=2)  # 截止时间
        self.filter(create_time__lte=end_time, result=0).update(result=3)

    def invoice_orders(self, order_ids, user):
        """
        可以开发票的订单数据
        """
        return self.filter(id__in=order_ids, user=user, invoiced=0, result=1).exclude(payment=0)

    def invoice_orders_all(self):
        """
        可以开发票的订单数据
        """
        return self.filter(invoiced=0, result=1).exclude(payment=0)

    def invoice_orders_cash(self, order_ids, user):
        return self.invoice_orders(order_ids, user).aggregate(cash=Sum("payment")).get("cash")

    def base_orders(self):
        return self.filter(result=1)

    def index_order(self, channel, start_time=None, coffee_client=None, filter_client=False):
        """
        后台首页订单
        """
        orders = self.base_orders()
        # queryset = filter_channel_1(orders, channel)
        if channel is None:
            orders = self.base_orders()
        elif isinstance(channel, str):
            channel_instance = Channel.objects.get(key=channel)
            if channel_instance.channel_type == 1:
                orders = filter_channel_1(orders, channel_instance, filter_client)
            elif channel_instance.channel_type == 2:
                orders = filter_channel_2(orders, channel_instance, filter_client)
            else:
                orders = filter_channel_3(orders, channel_instance, filter_client)
        else:
            if channel.channel_type == 1:
                orders = filter_channel_1(orders, channel, filter_client)
            elif channel.channel_type == 2:
                orders = filter_channel_2(orders, channel, filter_client)
            else:
                orders = filter_channel_3(orders, channel, filter_client)
        if coffee_client:
            orders = orders.filter(coffee_client=coffee_client)
        if start_time:
            return orders.filter(create_time__gte=start_time)
        else:
            return orders

    def order_statistics(self, channel=None, start_time=None, coffee_client=None, filter_client=False):
        orders = self.index_order(channel, start_time, coffee_client, filter_client)
        data = orders.aggregate(cash=Sum("payment")).get("cash")
        data = data if data else 0
        return "%.2f" % (data / 100)

    def order_count(self, channel, start_time=None, coffee_client=None, filter_client=False):
        orders = self.index_order(channel, start_time, coffee_client, filter_client)
        return orders.count()

    def group_by_days_orders(self, channel, start_time=None, filter_client=False):
        """
        group by days
        """
        orders = self.index_order(channel, start_time, filter_client=filter_client)

        events_per_day = orders.annotate(
            day=TruncDate('create_time')
        ).values('day').annotate(
            cash=Sum('payment'),
            sale_count=Count('id')
        ).order_by("day")
        return events_per_day


class CoffeeOrder(models.Model):
    payType = ((0, "未付"),
               (1, "微信支付"),
               (2, "api支付,对方收款"),
               (3, "通联支付"),
               (4, "银联支付(公众号,h5链接)"),
               (97, "通联云微付款"),
               (98, "小程序支付"),
               (99, "免支付"),
               (101, "每天减一毛免支付"),
               )
    orderStatus = ((0, "未支付"), (1, "支付成功"), (2, "退款成功"), (3, "订单已取消"), (4, "退款已申请"))
    coffeeMakeResult = ((0, "制作未成功"), (1, "制作成功"), (3, "制作中"))
    invoiceStatus = ((0, "未申请"), (1, "申请"), (2, "开过"))
    coffee_make_result = models.IntegerField(choices=coffeeMakeResult, default=0, verbose_name="咖啡制作结果")
    goods = models.ForeignKey(Coffee, verbose_name="商品")
    channel = models.ForeignKey(Channel, verbose_name="渠道", blank=True,
                                null=True)  # 取到key和商家用户名是一样的  这里记录的channel是咖啡机所在的渠道
    coupon = models.ForeignKey(CouponInfo, verbose_name="对应的券", blank=True, null=True)
    user = models.ForeignKey(User, verbose_name="用户", related_name="user_coffee_orders_set")
    coffee_client = models.ForeignKey("CoffeeClient", related_name="client_coffee_order_set", verbose_name="咖啡机")
    pid = models.CharField(max_length=8, verbose_name="商品名称", blank=True, null=True)
    goods_name = models.CharField(max_length=16, verbose_name="商品名称")
    goods_image = models.CharField(max_length=256, verbose_name="商品图片", blank=True, null=True)
    result = models.IntegerField(verbose_name="支付结果", db_index=True, choices=orderStatus, default=0)
    payment = models.IntegerField(verbose_name="实付", default=0, help_text="微信可能配活动 cash_fee是减免后的价格，用cash_fee来更新payment，所以payment是减免后的价格，是用户实际付款价格")
    total_fee = models.IntegerField(verbose_name="微信应付", default=0, help_text="微信应付，对应微信订单中total_fee")
    cash = models.IntegerField(verbose_name="应付", default=0)
    num = models.IntegerField(verbose_name="数量", default=0)
    price = models.IntegerField(verbose_name="单价", default=0)
    pay_type = models.IntegerField(verbose_name="支付类型", default=0, choices=payType)
    orderNo = models.CharField(verbose_name="订单号(咖啡机给的订单号)", max_length=64, db_index=True)
    out_trade_no = models.CharField(verbose_name="交易订单号", max_length=64, db_index=True, blank=True, null=True)
    update_time = models.DateTimeField(verbose_name="状态更新时间", auto_now=True)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    refund = models.OneToOneField("supply_order.RefundRecord", verbose_name="退款详情", blank=True, null=True)

    pay_time = models.DateTimeField(verbose_name="支付时间", blank=True, null=True)
    jn_status = models.CharField(blank=True, null=True, verbose_name="制作接口返回状态", max_length=16)
    jn_message = models.CharField(blank=True, null=True, verbose_name="制作接口返回信息", max_length=256)
    invoiced = models.IntegerField(verbose_name="已经开过发票", default=0, choices=invoiceStatus)
    goods_tag = models.CharField(blank=True, null=True, verbose_name="优惠标识", max_length=32)
    # is_discount = models.BooleanField(default=False, verbose_name="是否使用了优惠")

    # 现金券
    # extra_coupon = models.CharField(blank=True, null=True, max_length=64, verbose_name="额外券", help_text="[]")
    objects = CoffeeOrderManager()

    class Meta:
        verbose_name = "咖啡订单"
        verbose_name_plural = verbose_name
        ordering = ("-id",)

    def update_result(self, pay_type=4, total_fee=None, payment=None, bank_code=None):
        if payment:
            self.payment = payment
        if total_fee:
            self.total_fee = total_fee
        else:
            self.total_fee = self.payment
        self.result = 1
        # 创建使用记录
        coffee_api = CoffeeApi(self.orderNo, self.coffee_client.sign, self.pid)
        response = coffee_api.member_pay()  # 请求制作咖啡机接口
        self.jn_status = response.get("status")
        self.jn_message = response.get("message")
        self.pay_time = datetime.datetime.now()
        self.pay_type = pay_type
        if response.get("status") == "success":
            self.coffee_make_result = 3  # 制作中
        self.save()
        # 只有在没使用券的情况下,并且支付成功了生成就生成一元兑换券(后来没兑换券了，改成了6元免费券)
        # if not self.coupon:
        # 给系统用户创建券 (给用户赠送系统券，后来注释掉了)
        # coupon_instance = CouponInfo.objects.one_create_by_normal(self.user, expire_days=30, c_type=2,
        #                                                           quota=100, name="立减券", status=2)
        # 增加一元兑换券逻辑（先注释掉，需要用户不参加活动才会生成一元兑换券）
        # coupon_instance = CouponInfo.objects.one_create_by_normal(self.user, expire_days=30, c_type=3,
        #                                                           quota=100, name="立减券", status=2,
        #                                                           limit=self.payment)
        # # 系统用户赠送给用户 一元兑换券c_type =3
        # GiveRecord.objects.create_record_by_system(1, 1, self.user, c_type=3,
        #                                            coupon=json.dumps([coupon_instance.id]),
        #                                            order_score=self)
        # 如果没用券，并且没优惠
        # print(self.total_fee, self.payment, "total_fee payment")
        # if self.total_fee == self.cash:
        #     self.exchange_coupon_give()
        # else:
        #     status = ReduceMoneyEveryDay.objects.create_data(self.user.id)
        # 如果有优惠更新优惠记录 (微信应付,微信实付)
        if self.total_fee > self.payment:
            # 说明有优惠
            discount_instance = BankDiscount.objects.get_instance(bank_code, pay_type)
            UserBankDiscountNum.objects.create_or_update_record(self.user.id, discount_instance)
        return self

    def exchange_coupon_give(self):
        # 增加一元兑换券逻辑（先注释掉，需要用户不参加活动才会生成一元兑换券）
        # if self.goods.c_type == 1:
        #     c_type = 3
        # else:
        #     c_type = 8

        # 两元通用兑换券c_type = 9
        c_type = 9
        coupon_instance = CouponInfo.objects.one_create_by_normal(self.user, expire_days=30, c_type=c_type,
                                                                  quota=200, name="立减券", status=2,
                                                                  limit=self.payment)
        # 系统用户赠送给用户
        GiveRecord.objects.create_record_by_system(1, 1, self.user, c_type=c_type,
                                                   coupon=json.dumps([coupon_instance.id]),
                                                   order_score=self)

    def cancel_order(self):
        self.coupon.used = False
        self.coupon.save()
        self.save()

    def refund_coupon(self, result=2, refund=None):
        self.refund = refund
        self.result = result
        if self.coupon:  # 如果使用了券，就退还券
            self.coupon.used = False
            self.coupon.save()
            # 将使用记录改成退还
            self.use_record.status = 2  # 将使用记录改成退回
            self.use_record.save()
        if self.coffee_make_result == 3:  #
            self.coffee_make_result = 2
        self.save()
        return self

    def update_coffee_make_result(self, coffee_make_result):
        self.coffee_make_result = coffee_make_result

        if coffee_make_result == 1:
            try:
                if hasattr(self, "giverecord"):
                    self.giverecord.status = 1
                    coupon_id_list = self.giverecord.coupon
                    CouponInfo.objects.filter(id__in=json.loads(coupon_id_list)).update(status=1)

                    #     coupon_instance = CouponInfo.objects.one_create_by_normal(self.user, expire_days=30, c_type=3,
                    #                                                               quota=100,
                    #                                                               name="兑换券")
                    # GiveRecord.objects.create_record_by_system(1, 1, self.user, c_type=3,
                    #                                            coupon=json.dumps([coupon_instance.id]))
                # 通过拉新来获得优惠券
                if self.coupon.is_laxin:
                    # 通过好友分享寻求到分享用户
                    share_instance = ShareFriend.objects.filter(user_id=self.user.id).first()
                    if share_instance and not share_instance.status:
                        share_id = share_instance.share_id
                        from .utils import share_data
                        num, name, channel, expire_time, create_time, c_type, quota = share_data()
                        CouponInfo.objects.bulk_create_by_normal(num, name, share_id, channel, expire_time,
                                                                 create_time, c_type, quota=quota)  # 不让分享
                        share_instance.status = 1
                        share_instance.success_time = datetime.datetime.now()
                        share_instance.save()
                # 更新次数
            except Exception as e:
                print(e, " geng xin quan")

        print("self.coffee_make_result = coffee_make_result", self.coffee_make_result)
        GoodsTagLevel.objects.update_num(self.goods_tag)
        self.save()


# 生成券
class CouponMake(models.Model):
    weeks = models.CharField(verbose_name="星期选项", max_length=16, default="1,2,3,4,5,6,7",
                             help_text="1,2表示星期一和星期二。中间请用英文逗号隔开")
    active_key = models.CharField(verbose_name="活动key", max_length=16, default="0")
    is_special = models.BooleanField(default=False, verbose_name="特殊(特定渠道机器使用)")
    # client = models.ForeignKey("CoffeeClient", blank=True, null=True, verbose_name="适用设备")
    channel = models.ForeignKey("Channel", verbose_name="渠道")
    num = models.IntegerField(verbose_name="生成数量")
    name = models.CharField(verbose_name="券名称", max_length=16)
    quota = models.IntegerField(default=0, verbose_name="额度", help_text="只有立减券有额度")
    expire_time = models.IntegerField(default=365, verbose_name="有效期时长")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    c_type = models.IntegerField(verbose_name="券的类型", choices=CouponInfo.cType, db_index=True)
    # user = models.ForeignKey(User, verbose_name="用户")
    mobile = models.CharField(verbose_name="用户手机号", max_length=32, db_index=True)
    everyday_make = models.BooleanField(verbose_name="是否每天生成", default=False, db_index=True)
    make_expire_time = models.DateField(default=datetime.datetime.today() + relativedelta(years=1),
                                        verbose_name="每天生成截止时间")
    expire_day = models.DateField(blank=True, null=True, verbose_name="截止有效期(优先使用此时间)",
                                  help_text="如果有这个日期，那么就不用上面的有效时长了")
    can_share = models.BooleanField(verbose_name="可以分享", default=True)
    sales_type = models.IntegerField(default=1, choices=CouponInfo.salesType, verbose_name="消费类型")

    class Meta:
        verbose_name = "生成券"
        verbose_name_plural = verbose_name
        ordering = ("id",)

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        super(CouponMake, self).save(force_insert=force_insert, force_update=force_update, using=using,
                                     update_fields=update_fields)
        num = self.num
        user = User.objects.get(mobile=self.mobile)
        if self.expire_day:
            expire_time = self.expire_day
        else:
            expire_time = datetime.date.today() + datetime.timedelta(days=self.expire_time)
        CouponInfo.objects.bulk_create_by_normal(num, self.name, user, self.channel, expire_time,
                                                 self.create_time, self.c_type, quota=self.quota,
                                                 active_key=self.active_key, is_special=self.is_special,
                                                 can_share=self.can_share, sales_type=self.sales_type)
        return self


# Coupon订单
class CouponOrders(models.Model):
    payType = ((0, "未付"),
               (1, "微信支付"),
               (2, "api支付,对方收款"),
               (3, "通联支付"),
               (4, "银联支付(公众号,h5链接)"),
               (98, "小程序支付"),
               (99, "免支付"),
               )
    scoreType = ((1, "支付处"), (2, "普通购买"))
    orderStatus = ((0, "未支付"), (1, "支付成功"), (2, "退款成功"), (3, "订单已取消"), (4, "退款已申请"))
    score = models.IntegerField(verbose_name="来源", choices=scoreType, default=1)
    user = models.ForeignKey(User, verbose_name="用户")
    payment = models.IntegerField(verbose_name="金额", default=0)
    pay_type = models.IntegerField(verbose_name="支付类型", default=0, choices=payType)
    pay_time = models.DateTimeField(verbose_name="支付时间", blank=True, null=True)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    out_trade_no = models.CharField(verbose_name="交易订单号", max_length=64, db_index=True, blank=True, null=True)
    result = models.IntegerField(verbose_name="支付结果", db_index=True, choices=orderStatus, default=0)
    coupon = models.OneToOneField(CouponInfo, verbose_name="对应的券", blank=True, null=True)
    update_time = models.DateTimeField(verbose_name="更新时间", auto_now=True)

    class Meta:
        verbose_name = "券订单"
        verbose_name_plural = verbose_name

    def update_result(self, pay_type=98):
        self.result = 1
        # 创建使用记录
        self.pay_time = datetime.datetime.now()
        self.pay_type = pay_type
        self.save()
        return self


# ------------------用户分享---------------
class UserShare(models.Model):
    user_id = models.IntegerField(db_index=True, verbose_name="分享人id")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")

    class Meta:
        verbose_name = "用户分享"
        verbose_name_plural = verbose_name


class ReceiveShared(models.Model):
    share_id = models.IntegerField(verbose_name="分享id", db_index=True)
    user_id = models.IntegerField(verbose_name="领取人id", db_index=True)
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")

    class Meta:
        verbose_name = "领取分享"
        verbose_name_plural = verbose_name


# ------------------购物车------------------
class ShopCar(models.Model):
    user_id = models.IntegerField(verbose_name="用户id")
    coffee_id = models.ForeignKey(Coffee, verbose_name="商品id")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    num = models.IntegerField(verbose_name="数量")
    update_time = models.DateTimeField(verbose_name="更新时间", auto_now=True)
    status = models.BooleanField(default=True, verbose_name="状态")

    class Meta:
        verbose_name = "购物车"
        verbose_name_plural = verbose_name


# -------------------------------------随机券------------------------------------------
class RandomCouponRecord(models.Model):
    share_id = models.IntegerField(verbose_name="分享id", db_index=True)
    user_id = models.IntegerField(verbose_name="领取人id", blank=True, null=True)
    coupon = models.OneToOneField(CouponInfo, verbose_name="券", blank=True, null=True)
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    receive_time = models.DateTimeField(verbose_name="领取时间", blank=True, null=True)

    class Meta:
        verbose_name = "随机券"
        verbose_name_plural = verbose_name


# -------------------------------------------季卡---------------------------------------
class CardBag(models.Model):
    """
    卡包商品信息
    """
    cardType = ((1, "98"), (2, "198"))
    card_type = models.IntegerField(verbose_name="卡包类型", default=1, choices=cardType)
    ordering = models.IntegerField(verbose_name="排序", default=1)
    can_sales = models.BooleanField(verbose_name="上架", default=True, db_index=True)
    coupon_type = models.CharField(
        verbose_name="券类型",
        help_text="用逗号隔开 (1, 免费A), (2, 立减券), (3, 兑换券A), (6, 免费B),(7, 通用免费券),(8, 兑换券B)",
        max_length=32)
    coupon_quota = models.CharField(verbose_name="额度", help_text="用逗号隔开, 免费券是0", max_length=32)
    coupon_num = models.CharField(verbose_name="数量", help_text="用逗号隔开", max_length=32)
    name = models.CharField(verbose_name="名称", max_length=32)
    price = models.IntegerField(verbose_name="价格")
    real_price = models.IntegerField(verbose_name="真实价格", default=0)
    bank = models.CharField(verbose_name="银行名称", max_length=16, blank=True, null=True)
    label = models.CharField(verbose_name="标签", max_length=16, blank=True, null=True)
    use_explain = models.CharField(verbose_name="使用说明", max_length=32)
    details_img = models.CharField(verbose_name="详情图", max_length=256, blank=True, null=True)
    expire = models.IntegerField(verbose_name="有效期", help_text="天")
    text_expire_time = models.CharField(verbose_name="文字有效期", max_length=64, blank=True, null=True)
    logo = models.CharField(verbose_name="LOGO", max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = "卡券包"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.get_card_type_display()


class UserCardBagManager(models.Manager):
    def create_card_bag(self, bag_orders_instance):
        cardbag = bag_orders_instance.goods
        expire = cardbag.expire
        now_day = datetime.datetime.today()
        end_time = now_day + datetime.timedelta(days=expire)
        out_trade_no = bag_orders_instance.bag_orders_instance
        user_id = bag_orders_instance.user.id
        return self.create(
            cardbag=cardbag,
            out_trade_no=out_trade_no,
            user_id=user_id,
            expire=expire,
            expire_day=end_time
        )

    def group_by_bag_type(self, queryset):
        return queryset.values("cardbag__card_type", "cardbag__price", "expire_day").annotate(counts=Count("id"))


class CardBagRecordManager(models.Manager):
    def create_bag_record(self, user_card_bag_instance):
        own_user = user_card_bag_instance.user_id
        user_card_bag = user_card_bag_instance
        card_bag = user_card_bag_instance.cardbag
        record_id = uuid.uuid4().hex
        return self.create(
            own_user=own_user,
            user_card_bag=user_card_bag,
            record_id=record_id,
            card_bag=card_bag,
        )


class CardBagRecord(models.Model):
    receiveStatus = ((1, "已接收"), (2, "未接收"), (3, "已返回"))
    giveType = ((1, "分享链接"), (2, "扫码"), (3, "手机号"), (4, "系统赠送"),)
    record_id = models.CharField(max_length=32, db_index=True)
    give_type = models.IntegerField(verbose_name="赠送方式", choices=giveType, default=2)
    card_bag = models.ForeignKey(CardBag, verbose_name="卡包")
    user_card_bag = models.ForeignKey("UserCardBag", verbose_name="用户卡包")
    status = models.IntegerField(verbose_name="状态接收", choices=receiveStatus, default=2)
    own_user = models.IntegerField(verbose_name="拥有用户")
    receive_user = models.IntegerField(verbose_name="接收用户", blank=True, null=True)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    update_time = models.DateTimeField(verbose_name="更新时间", auto_now=True)
    objects = CardBagRecordManager()

    class Meta:
        verbose_name = "卡包转增记录"
        verbose_name_plural = verbose_name

    def update_receive_info(self, receive_user):
        if isinstance(receive_user, User):
            receive_user = receive_user.id
        self.receive_user = receive_user
        self.update_time = datetime.datetime.now()
        self.status = 1
        self.save()

    def update_status_3(self):
        self.status = 3
        self.user_card_bag.giving = False
        self.user_card_bag.save()
        self.save()


# 用户卡包列表
class UserCardBag(models.Model):
    makeType = ((1, "购买"), (2, "后台生成"))
    bagStatus = ((1, "未拆"), (2, "已拆"), (3, "过期"))
    giving = models.BooleanField(verbose_name="赠送中", default=False)
    expired = models.BooleanField(default=False)
    user_id = models.IntegerField(verbose_name="用户")
    cardbag = models.ForeignKey(CardBag, verbose_name="卡包信息")
    make_type = models.IntegerField(verbose_name="生成类型", default=1, choices=makeType)
    bag_status = models.IntegerField(verbose_name="卡包状态", default=1, choices=bagStatus)
    refund_coupon_ids = models.CharField(verbose_name="退款券列表", max_length=128, blank=True, null=True)
    out_trade_no = models.CharField(verbose_name="付款订单号", max_length=64, db_index=True, default=0)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    expire = models.IntegerField(verbose_name="有效期", help_text="天", default=365)
    expire_day = models.DateField(verbose_name="截至有效期")
    unpacking_datetime = models.DateTimeField(verbose_name="拆包时间", blank=True, null=True)
    objects = UserCardBagManager()

    class Meta:
        verbose_name = "用户卡券包"
        verbose_name_plural = verbose_name

    def unpacking(self):
        coupon_type = self.cardbag.coupon_type.split(",")
        coupon_quota = self.cardbag.coupon_quota.split(",")
        coupon_num = self.cardbag.coupon_num.split(",")
        expire = self.expire
        user_id = self.user_id
        for i in range(len(coupon_type)):
            quota = int(coupon_quota[i])
            c_type = int(coupon_type[i])
            c_num = int(coupon_num[i])
            coupon_name = None
            for cType in CouponInfo.cType:
                if cType[0] == c_type:
                    coupon_name = cType[1]
                    break
            CouponInfo.objects.create_coupon(
                c_num, user_id, c_type=c_type, channel="kabaogoumai",
                name=coupon_name, expire_days=expire, quota=quota, bag=self.pk
            )
        self.bag_status = 2
        self.unpacking_datetime = datetime.datetime.now()
        self.save()

    def update_giving(self):
        self.giving = 1
        self.save()

    def update_user(self, user_id):
        self.giving = 0
        self.user_id = user_id
        self.save()


class CardBagOrders(models.Model):
    payType = ((0, "未付"),
               (1, "微信支付"),
               (2, "api支付,对方收款"),
               (3, "通联支付"),
               (4, "银联支付(公众号,h5链接)"),
               (98, "小程序支付"),
               (99, "免支付"),
               )
    scoreType = ((1, "支付处"), (2, "普通购买"))
    orderStatus = ((0, "未支付"), (1, "支付成功"), (2, "退款成功"), (3, "订单已取消"), (4, "发起退款"), (5, "已使用"))
    score = models.IntegerField(verbose_name="来源", choices=scoreType, default=1)
    user = models.ForeignKey(User, verbose_name="用户")
    payment = models.IntegerField(verbose_name="金额", default=0)
    pay_type = models.IntegerField(verbose_name="支付类型", default=0, choices=payType)
    pay_time = models.DateTimeField(verbose_name="支付时间", blank=True, null=True)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    out_trade_no = models.CharField(verbose_name="交易订单号", max_length=64, db_index=True, blank=True, null=True)
    result = models.IntegerField(verbose_name="支付结果", db_index=True, choices=orderStatus, default=0)
    goods = models.OneToOneField(CardBag, verbose_name="对应的商品")
    goods_name = models.CharField(verbose_name="商品名", default="", max_length=32)
    update_time = models.DateTimeField(verbose_name="更新时间", auto_now=True)
    refund = models.OneToOneField("supply_order.RefundRecord", verbose_name="退款详情", blank=True, null=True)

    class Meta:
        verbose_name = "卡包订单"
        verbose_name_plural = verbose_name

    def update_card_bag_order(self, pay_type=98):
        """
        支付成功
        :param pay_type:
        :return:
        """
        self.pay_type = pay_type
        self.pay_time = datetime.datetime.now()
        self.result = 1
        self.save()
        UserCardBag.objects.create_card_bag(self)
        return self

    def update_refund(self, refund, result=2):
        self.refund = refund
        self.result = result
        self.save()
        return self


class BankExchangeCode(models.Model):
    code = models.CharField(verbose_name="券号", max_length=26, db_index=True)
    bank = models.CharField(verbose_name="渠道", max_length=16)
    num = models.IntegerField(verbose_name="包含的数量")
    quota = models.IntegerField(default=0, verbose_name="额度(以分为单位)", help_text="只有立减券有额度")
    c_type = models.IntegerField(choices=CouponInfo.cType, default=1)
    used = models.BooleanField(default=False, verbose_name="被使用")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    expire_time = models.DateField(default=datetime.datetime.today() + relativedelta(years=1),
                                   verbose_name="有效期")
    name = models.CharField(verbose_name="券名称", max_length=16)
    channel = models.ForeignKey("Channel", verbose_name="渠道")
    user_id = models.IntegerField(verbose_name="领取人", default=0, db_index=True)
    receive_time = models.DateTimeField(blank=True, null=True, verbose_name="领取时间")

    class Meta:
        verbose_name = "银行兑换码"
        verbose_name_plural = verbose_name

        # def save(self, force_insert=False, force_update=False, using=None,
        #          update_fields=None):
        #     super(BankExchangeCode, self).save(force_insert=force_insert, force_update=force_update, using=using,
        #                                  update_fields=update_fields)
        #     num = self.num
        #     user = User.objects.get(mobile=self.mobile)
        #     expire_time = datetime.date.today() + + datetime.timedelta(days=self.expire_time)
        #     CouponInfo.objects.bulk_create_by_normal(num, self.name, user, self.channel, expire_time,
        #                                              self.create_time, self.c_type, quota=self.quota)
        #     return self


class ReduceMoneyEveryDayManager(models.Manager):
    def get_last_data(self, user_id):
        return self.filter(user_id=user_id).order_by("-id")

    def create_data(self, user_id, reduce_date=None):
        status = False
        # 报名后才可以
        if ReduceMoneyEveryDayActive.objects.filter(user_id=user_id).exists():
            today = datetime.date.today()
            # 如果报名但是不能减钱也不成功
            if is_workday(today):
                queryset = self.get_last_data(user_id)
                if queryset.exists():
                    instance = queryset.first()
                    reduce_date = instance.reduce_date
                    money = instance.money
                    if today != reduce_date:
                        self.create(
                            user_id=user_id,
                            money=money + 10,
                            reduce_date=today,
                        )
                        status = True
        return status


# 每天减一毛
class ReduceMoneyEveryDay(models.Model):
    user_id = models.IntegerField(db_index=True, verbose_name="用户")
    money = models.IntegerField(verbose_name="减钱金额(分)")
    reduce_date = models.DateField(verbose_name="减钱日期", default=datetime.date.today)
    create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
    objects = ReduceMoneyEveryDayManager()

    class Meta:
        verbose_name = "每天减钱"
        verbose_name_plural = verbose_name


class ReduceMoneyEveryDayActive(models.Model):
    """
    报名参加活动表
    """
    user_id = models.IntegerField(db_index=True, verbose_name="用户")
    create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)

    class Meta:
        verbose_name = "每天减钱活动"
        verbose_name_plural = verbose_name


# 生成券(多个商家，每小时抢券)
class CouponMakeEveryHour(models.Model):
    channel_key = models.CharField(max_length=32, verbose_name="渠道码", help_text="池子渠道")
    name = models.CharField(max_length=32, verbose_name="券名称")
    time_slot = models.CharField(verbose_name="时间段", max_length=64)
    mapping_num = models.CharField(verbose_name="对应数量", help_text="与时间一一对应", max_length=64)
    coupon_expire_time = models.IntegerField(default=1, verbose_name="券有效期", help_text="天数")
    c_type = models.IntegerField(verbose_name="券的类型", choices=CouponInfo.cType, db_index=True)
    quota = models.IntegerField(default=0, verbose_name="额度", help_text="只有立减券有额度")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    start_time = models.DateTimeField(default=timezone.now, verbose_name="开始时间")
    end_time = models.DateTimeField(default=datetime.datetime.today() + relativedelta(years=1), verbose_name="截至时间")

    class Meta:
        verbose_name = "商家抢券功能"
        verbose_name_plural = verbose_name
        ordering = ("id",)


class GroupQrCode(models.Model):
    name = models.CharField(verbose_name="名称", max_length=32)
    url = models.CharField(max_length=256, verbose_name="二维码图片地址")
    show = models.BooleanField(verbose_name="显示", default=True)

    class Meta:
        verbose_name = "企业群聊二维码"
        verbose_name_plural = verbose_name


class ShopInfo(models.Model):
    name = models.CharField(verbose_name="门店名称", max_length=32)
    lat = models.CharField(verbose_name="经度", max_length=32)
    lon = models.CharField(verbose_name="维度", max_length=32)
    addr = models.CharField(verbose_name="门店位置", max_length=32)
    h5_active = models.ForeignKey("MakeH5", verbose_name="对应的H5", related_name="h5_shop_set")

    class Meta:
        verbose_name = "门店信息"
        verbose_name_plural = verbose_name


class MakeH5(models.Model):
    Rules = (
        (1, "每人一次"),
        (2, "每天一次"),
        (3, "每天两次"),
    )
    banner = models.TextField(verbose_name="banner")
    channel = models.ForeignKey("Channel", verbose_name="渠道")
    key = models.CharField(max_length=32, verbose_name="标识")
    show = models.BooleanField(default=True, verbose_name="是否显示")
    title = models.CharField(max_length=256, verbose_name="标题")
    expire_time = models.IntegerField(verbose_name="有效期")
    num = models.IntegerField(verbose_name="数量")
    c_type = models.IntegerField(verbose_name="券的类型", choices=CouponInfo.cType)
    quota = models.IntegerField(default=0, verbose_name="额度", help_text="只有立减券有额度")
    c_name = models.CharField(max_length=16, verbose_name="券名称")
    use_explain = models.TextField(verbose_name="说明")
    use_method = models.TextField(verbose_name="使用方法")
    info = models.TextField(verbose_name="商品详情")
    active_time = models.DateTimeField(default=timezone.now, verbose_name="活动开始时间")
    count = models.IntegerField(verbose_name="活动总数量", default=100)
    rules = models.IntegerField(verbose_name="一天两次/一天一次", default=1, choices=Rules)
    background = models.CharField(verbose_name="背景图", default="", max_length=256)

    class Meta:
        verbose_name = "制作H5"
        verbose_name_plural = verbose_name


class InvoiceInfo(models.Model):
    invoiceType = ((1, "公司"), (2, "个人"))
    full_name = models.CharField(max_length=64, verbose_name="名称")
    invoice_type = models.IntegerField(choices=invoiceType, default=1)
    card_num = models.CharField(max_length=32, verbose_name="税号")
    email_addr = models.CharField(max_length=64, verbose_name="邮箱", default="")
    username = models.CharField(verbose_name="用户", max_length=32)
    is_default = models.BooleanField(default=True, verbose_name="默认值")

    class Meta:
        verbose_name = "发票信息"
        verbose_name_plural = verbose_name
        ordering = ("-is_default", "-id")

    def __str__(self):
        return f"{self.full_name} {self.card_num} {self.email_addr}"


class InvoiceRecord(models.Model):
    full_name = models.CharField(max_length=64, verbose_name="名称")
    invoice_type = models.IntegerField(choices=InvoiceInfo.invoiceType, default=1)
    card_num = models.CharField(max_length=32, verbose_name="税号")
    email_addr = models.CharField(max_length=64, verbose_name="邮箱")
    order_ids = models.TextField()
    cash = models.IntegerField()
    create_time = models.DateTimeField(default=timezone.now)
    username = models.CharField(verbose_name="用户", max_length=32)
    pdf = models.CharField(verbose_name="发票地址", default="", max_length=512)
    ready = models.BooleanField(default=False, verbose_name="已经开过")

    class Meta:
        verbose_name = "发票记录"
        verbose_name_plural = verbose_name


# 生成小程序码
class CodeQR(models.Model):
    key = models.CharField(max_length=16, verbose_name="对应渠道的Key")
    name = models.CharField(max_length=32, verbose_name="渠道名称", help_text="渠道名称方便查找")
    url = models.CharField(blank=True, null=True, verbose_name="产生的url", max_length=256, help_text="不需要填")
    c_type = models.IntegerField(verbose_name="券的类型", choices=CouponInfo.cType, default=7)
    quota = models.CharField(verbose_name="券金额", default=0, max_length=10)

    class Meta:
        verbose_name = "小程序码"
        verbose_name_plural = verbose_name

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        from script.coffee.miniQrcode import make_mini_code
        self.url = make_mini_code(channel_key=self.key, quota=self.quota, c_type=self.c_type)
        return super(CodeQR, self).save()


class LiftMobile(models.Model):
    mobile = models.CharField(max_length=11, verbose_name="手机号")

    class Meta:
        verbose_name = "解除手机号"
        verbose_name_plural = verbose_name

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        User.objects.filter(mobile=self.mobile, username=self.mobile).update(
            wx_mini_user=None
        )
        return super(LiftMobile, self).save()


# 会员
class MemberCenter(models.Model):
    Level = (
        (0, "非会员"),
        (1, "铂金会员"),
        (2, "钻石会员"),
    )
    level = models.IntegerField(verbose_name="等级", choices=Level, default=2)
    user_id = models.IntegerField(verbose_name="用户标识")
    create_time = models.DateTimeField(verbose_name="创建时间")
    expire_time = models.DateField(verbose_name="截止有效期")
    url = models.CharField(verbose_name="图片地址", max_length=256, blank=True, null=True)
    finished = models.BooleanField(default=False, verbose_name="是否配完")
    mobile = models.CharField(max_length=11, verbose_name="用户手机号")
    sign = models.CharField(max_length=16, verbose_name="待定", blank=True, null=True)

    class Meta:
        verbose_name = "会员管理"
        verbose_name_plural = verbose_name


# 会员图片
class MemberAddr(models.Model):
    level = models.IntegerField(verbose_name="等级", choices=MemberCenter.Level, default=2)
    url = models.CharField(verbose_name="图片地址", max_length=256)
    sign = models.CharField(max_length=16, verbose_name="渠道标识")
    icon = models.CharField(max_length=256, verbose_name="图标url", blank=True, null=True)

    class Meta:
        verbose_name = "会员图片管理"
        verbose_name_plural = verbose_name


class ShareFriend(models.Model):
    share_id = models.IntegerField(verbose_name="分享id")
    user_id = models.IntegerField(verbose_name="被分享人id")  # 被分享人
    create_time = models.DateTimeField(verbose_name="創建時間", default=timezone.now)
    success_time = models.DateTimeField(verbose_name="邀請成功時間", blank=True, null=True)
    status = models.BooleanField(default=False, verbose_name="邀請成功")

    class Meta:
        verbose_name = "好友分享記錄"
        verbose_name_plural = verbose_name


class ShareFriend(models.Model):
    share_id = models.IntegerField(verbose_name="分享id")
    user_id = models.IntegerField(verbose_name="被分享人id")  # 被分享人
    create_time = models.DateTimeField(verbose_name="創建時間", default=timezone.now)
    success_time = models.DateTimeField(verbose_name="邀請成功時間", blank=True, null=True)
    status = models.BooleanField(default=False, verbose_name="邀請成功")

    class Meta:
        verbose_name = "好友分享記錄"
        verbose_name_plural = verbose_name

class BankDiscountManager(models.Manager):
    def get_instance(self, bank_code, pay_type):
        queryset = self.filter(bank_code=bank_code, pay_type=pay_type, show=True)
        return queryset.first()


class BankDiscount(models.Model):
    countType = ((1, "年"), (2, "月"), (3, "每天一次"),)
    bank_code = models.CharField(max_length=10, blank=True, null=True, verbose_name="银行编号")
    bank_name = models.CharField(max_length=26, blank=True, null=True, verbose_name="银行名称")
    num = models.IntegerField(verbose_name="优惠次数")
    title = models.CharField(verbose_name="标题", max_length=128)
    show = models.BooleanField(verbose_name="显示", default=True)
    pay_type = models.IntegerField(choices=CoffeeOrder.payType, default=98, verbose_name="支付方式")
    count_type = models.IntegerField(choices=countType, default=1, verbose_name="计算类型")
    objects = BankDiscountManager()

    class Meta:
        verbose_name = "优惠显示"
        verbose_name_plural = verbose_name



class UserBankDiscountNumManager(models.Manager):
    def create_or_update_record(self, user_id:int, data:BankDiscount):
        if not data:
            return None
        pay_type = data.pay_type
        bank_code = data.bank_code
        count_type = data.count_type
        today = datetime.date.today()
        year = today.year
        month = today.month
        if pay_type == 2:
            # 云闪付不考虑卡 全部都记录
            queryset = self.filter(pay_type=pay_type, user_id=user_id, count_type=count_type)
        else:
            if count_type == 1:
                queryset = self.filter(create_year=year, bank_code=bank_code, pay_type=pay_type, user_id=user_id, count_type=count_type)
            elif count_type == 2:
                queryset = self.filter(create_year=year, create_month=month, bank_code=bank_code, pay_type=pay_type, user_id=user_id, count_type=count_type)
            elif count_type == 3:
                queryset = self.filter(create_year=year, create_month=month, bank_code=bank_code, pay_type=pay_type,
                                       user_id=user_id, count_type=count_type, create_day=today)
            else:
                raise Exception("countType error")
        instance = queryset.first()
        if instance:
            instance.num = F("num") + 1
            instance.save()
        else:
            instance = self.create(
                create_year=year,
                create_month=month,
                num=1,
                user_id=user_id,
                pay_type=pay_type,
                count_type=count_type,
            )
        return instance


class UserBankDiscountNum(models.Model):
    create_year = models.CharField(max_length=4, verbose_name="年")
    create_month = models.CharField(max_length=2, verbose_name="月")
    num = models.IntegerField(verbose_name="优惠次数")
    user_id = models.IntegerField(verbose_name="用户id")
    pay_type = models.IntegerField(choices=CoffeeOrder.payType, default=98, verbose_name="支付方式")
    # 有可能是CMB_CREDIT编号, 有可能是卡号 微信是CMB_CREDIT编号 云闪付是卡号
    bank_code = models.CharField(max_length=10, blank=True, null=True, verbose_name="银行编号")
    create_day = models.DateField(default=timezone.now)
    create_time = models.DateTimeField(default=timezone.now)
    count_type = models.IntegerField(choices=BankDiscount.countType, default=1, verbose_name="计算类型")
    objects = UserBankDiscountNumManager()

    class Meta:
        verbose_name = "优惠次数统计"
        verbose_name_plural = verbose_name

class GoodsTagLevelManager(models.Manager):
    def update_num(self, goods_tag):
        instance = self.filter(goods_tag=goods_tag).first()
        print(instance, "update_num goods_tag")
        if instance:
            instance.num = F("num") - 1
            instance.save()

    def num_gt_0(self, goods_tag):
        instance = self.filter(goods_tag=goods_tag).first()
        return instance.num > 0

class GoodsTagLevel(models.Model):
    goods_tag = models.CharField(max_length=13, verbose_name="优惠标识")
    num = models.IntegerField(verbose_name="数量", default=99)
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    update_time = models.DateTimeField(default=timezone.now, verbose_name="更新时间")
    expired_date = models.DateField(default=timezone.now, verbose_name="过期时间")
    objects = GoodsTagLevelManager()

    class Meta:
        verbose_name = "优惠标识优先级"
        verbose_name_plural = verbose_name


class PayTitle(models.Model):
    show = models.BooleanField(
        default=True,
        verbose_name="是否显示"
    )

    # 咖啡机ID - 字符字段，可以根据需要调整最大长度
    client_id = models.CharField(
        max_length=50,
        verbose_name="咖啡机ID"
    )

    # 标题 - 字符字段
    title = models.CharField(
        max_length=200,
        verbose_name="标题"
    )

    # 支付类型 - 使用选择字段
    PAY_TYPE_CHOICES = [
        ('wx', '微信'),
        ('ysf', '云闪付'),
    ]
    pay_type = models.CharField(
        max_length=20,
        choices=PAY_TYPE_CHOICES,
        default='wx',
        verbose_name="支付类型"
    )

    class Meta:
        verbose_name = "咖啡机优惠标题"
        verbose_name_plural = "咖啡机优惠标题"

